import json
import logging

from HttpTestcase.core.analysis_headers import analysis_args
from apps.HttpTestcase.core.validators import Validator
from apps.HttpTestcase.core.extractor import Extractor
from apps.HttpTestcase.core.http_global_variable_pool import Variable_Pool

logger = logging.getLogger('log')


class HttpTestcaseDebug(object):
    def __init__(self, http_session=None, name=None, url=None, method=None, cookies=None,http_session_params=None,
                 headers=None, request_data_type=None, json_data=None, form_data=None, expect_result=None, params_data=None):
        self.http_session = http_session
        self.name = name
        self.url = url
        self.method = method
        self.headers = headers
        self.request_data_type = request_data_type
        self.json_data = json_data
        self.form_data = form_data
        self.params_data = params_data
        self.expect_result = expect_result
        self.http_session_params = http_session_params

    def debug(self):
        logger.info(f'=============== 调试用例:【{self.name}】===============')

        # 判断header、request_data类型，不为str转换
        headers = self.headers if isinstance(self.headers, str) else json.dumps(self.headers)
        logger.info('请求头信息：{headers}'.format(headers=self.headers))
        request_data = self.json_data or self.form_data

        request_data = request_data if isinstance(request_data, str) else json.dumps(request_data)
        testcase_result = {
            "url": self.url,
            "method": self.method,
            "headers": headers,
            "request_data": request_data
        }
        logger.info('请求URL：{url}'.format(url=self.url))
        logger.info('请求方法：{method}'.format(method=self.method))
        logger.info('请求体参数类型：{request_data_type}'.format(request_data_type=self.request_data_type))

        params = {**self.http_session_params.variable,
                  **self.http_session_params.output_Variables}
        # 全局参数替换
        json_data = analysis_args(content=self.json_data, variables=params)
        json_data = None if not json_data else json.loads(json_data)

        form_data = analysis_args(content=self.form_data, variables=params)
        form_data = json.loads(form_data)

        params_data = analysis_args(content=self.params_data, variables=params)
        params_data = json.loads(params_data)
        logger.info('请求体参数：{request_data}'.format(request_data=form_data or json_data or params_data))
        request_kwargs = dict(
            headers=self.headers,
            data=form_data,
            json=json_data,
            params=params_data
        )

        logger.info('期望结果：{expect_result}'.format(expect_result=self.expect_result))

        res = self.http_session.request(url=self.url, method=self.method, **request_kwargs)
        res_key = res['response'].keys()
        actual_key = list(set(res_key).intersection(['results', 'text', 'content']))[0]
        res_value = ''
        if isinstance(res['response'][actual_key], str):
            res_value = res['response'][actual_key]
        else:
            res_value = json.dumps(res["response"][actual_key], ensure_ascii=False)

        logger.info(f'响应结果：{res_value}')
        http_global_variable = Variable_Pool()

        extractor_variable = None
        if isinstance(self.expect_result, dict) and self.expect_result.get('output'):
            # 初始化提取器
            extractor = Extractor()
            extractor.format_output(self.expect_result.get('output'))
            extractor_variable = extractor.extract_output(res["response"])
            http_global_variable.update_output_variable(var=extractor_variable)

        # 断言 创建校验器
        validator = Validator()

        # 格式化validate
        validator.uniform_validate(self.expect_result.get('validate'))

        # 校验预期结果与实际结果
        results, calibration = validator.validate(res_obj=res['response'])

        testcase_result = {
            "url": self.url,
            "method": self.method,
            "headers": json.dumps(self.headers, ensure_ascii=False),
            "request_data": json.dumps(self.json_data or self.form_data, ensure_ascii=False),
            "actual_status_code": res["response"]["status_code"],
            "actual_response_data": res_value,
            "execute_time": res["stat"]["execute_time"],
            "elapsed_ms": res["response"]["elapsed"],
            "status": results,
            'extract_value': extractor_variable
        }

        if results == 'FAIL':
            testcase_result.update({
                'failure_reason': json.dumps(calibration, ensure_ascii=False)
            })
            logger.warning('用例调试未通过；原因：{failure_reason}'.format(failure_reason=calibration))
        logger.warning(f'=============== 用例:【{self.name}】 调试结束===============')
        return testcase_result
